﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Treasland.MassiveGridMap.VO;

namespace Treasland.MassiveGridMap.Editor {
    public class MapNode : Node {
        private List<LayerNode> layerNodeList = new List<LayerNode>();
        private List<ConnectionPoint> connectPointList = new List<ConnectionPoint>();
        private List<Connection> connectionList = new List<Connection>();

        /// <summary>
        /// 当前正在操作的Connection
        /// </summary>
        private Connection currConnection = null;

        private GUIStyle style;
        private GUIStyle selectedStyle;
        private string title;
        private float boxWidth;
        private float boxHeight;
        private Rect boxRect;
        private Action<MapNode> onDeleteMapNodeCallback;
        private float minHeight = 100.0f;

        // Data
        private MapNodeVO mapNodeVO = null;

        // MapNode UI
        private float border = 10.0f;

        public MapNode(Vector2 _position, 
                       float _width,
                       float _height,
                       GUIStyle _mapNodeStyle,
                       GUIStyle _selectedStyle,
                       Action<MapNode> _onDeleteMapNodeCallback,
                       enNodeType _type = enNodeType.MapNode) : base(_type) {

            mapNodeVO = new MapNodeVO();

            boxWidth = _width;
            boxHeight = _height;
            boxHeight = Mathf.Clamp(boxHeight, minHeight, boxHeight);
            boxHeight += connectPointList.Count * GUIStyleUtil.outPointStyleImg.height;
            rect = new Rect(_position.x, _position.y, boxWidth, boxHeight);
            boxRect = new Rect(0, 0, boxWidth, boxHeight);
            Debug.Log(rect);
            style = _mapNodeStyle;
            selectedStyle = _selectedStyle;
            onDeleteMapNodeCallback = _onDeleteMapNodeCallback;

        }

        /// <summary>
        /// 处理所有跟地图节点有关的事件
        /// </summary>
        /// <param name="e"></param>
        public override bool ProcessEvent(Event e) {
            base.ProcessEvent(e);

            if (ProcessLayersEvent(e)) {
                return true;
            }

            if (e.type == EventType.MouseDown) {
                if (e.button == 1) {
                    if (!rect.Contains(e.mousePosition)) {
                        DrawCreateLayerNodeMenu(e.mousePosition);
                    } else {
                        DrawMapNodeMenu(e.mousePosition);
                    }
                }
                else if(e.button == 0 && rect.Contains(e.mousePosition)) {
                    if (nodeDragState != enNodeDragState.Lock) {
                        nodeDragState = enNodeDragState.ReadyDrag;
                    }
                }
            }

            if(e.type == EventType.MouseDrag) {
                if(nodeDragState == enNodeDragState.ReadyDrag) {
                    base.Drag(e.delta);
                }
            }

            return true;
        }

        /// <summary>
        /// 绘制地图节点及
        /// </summary>
        public override void Draw() {
            CorrectNodeSize();

            GUI.BeginGroup(rect);
            DrawConnectionPoints();
            // background
            GUI.Box(boxRect, "", style);

            // Left Area
            GUILayout.BeginArea(new Rect(border, border, boxWidth * 0.35f, boxHeight - border));
            GUILayout.Label("MAP NAME");
            GUILayout.Label("MAP ROW");
            GUILayout.Label("MAP COL");
            GUILayout.Label("GRID SIZE");
            GUILayout.EndArea();

            // Right Area
            GUILayout.BeginArea(new Rect(boxWidth * 0.35f + border, border, boxWidth * 0.65f - border * 2.5f, boxHeight - border));
            mapNodeVO.mapName = GUILayout.TextField(mapNodeVO.mapName, 10);
            mapNodeVO.mapRow = EditorGUILayout.IntField(mapNodeVO.mapRow);
            mapNodeVO.mapCol = EditorGUILayout.IntField(mapNodeVO.mapCol);
            mapNodeVO.gridSize = EditorGUILayout.FloatField(mapNodeVO.gridSize);
            GUILayout.EndArea();

            GUI.EndGroup();

            DrawLayerNodes();
        }


        public override void ForceDrag(Vector2 delta) {
            base.ForceDrag(delta);
            for(int i = 0; i < layerNodeList.Count; ++i) {
                layerNodeList[i].ForceDrag(delta);
            }
        }



        #region Curr Map Things
        private void CorrectNodeSize() {
            boxHeight = minHeight;
            int additionPoint = (connectPointList.Count - 4);
            additionPoint = Mathf.Clamp(additionPoint, 0, additionPoint);
            boxHeight += additionPoint * GUIStyleUtil.outPointStyleImg.height;

            rect.height = boxHeight;
            boxRect.height = boxHeight;
        }


        private void DrawConnectionPoints() {
            for (int i = 0; i < connectPointList.Count; ++i) {
                Rect rect = new Rect(boxWidth - 12 + GUIStyleUtil.outPointStyleImg.width / 2,
                                         border + GUIStyleUtil.outPointStyleImg.height * i,
                                         GUIStyleUtil.outPointStyleImg.width,
                                         GUIStyleUtil.outPointStyleImg.height);

                connectPointList[i].Draw(rect);
            }

        }

        /// <summary>
        /// 右键点击 Map 节点
        /// </summary>
        private void DrawMapNodeMenu(Vector2 pos) {
            GenericMenu genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent("Edit"),
                                false,
                                () => OnClickEditMapNode());
            genericMenu.AddItem(new GUIContent("Delete"),
                                false,
                                () => OnClickDeleteMapNode());
            genericMenu.AddItem(new GUIContent("Make Translation"),
                                false,
                                () => OnClickMakeTranslation());
            genericMenu.ShowAsContext();
        }

        /// <summary>
        /// 点击了编辑Map节点
        /// </summary>
        private void OnClickEditMapNode() {

        }

        /// <summary>
        /// 点击了删除Map节点
        /// </summary>
        private void OnClickDeleteMapNode() {
            if(onDeleteMapNodeCallback != null) {
                onDeleteMapNodeCallback(this);
            }
        }

        /// <summary>
        /// 点击了创建连接
        /// </summary>
        private void OnClickMakeTranslation() {
            Connection connection = new Connection(OnDeleteConnection);
            currConnection = connection;


            ConnectionPoint p = new ConnectionPoint(enConnectionPoint.OutPoint);
            connectPointList.Add(p);
        }

        /// <summary>
        /// 右键点击了空白处
        /// </summary>
        private void DrawCreateLayerNodeMenu(Vector2 pos) {
            GenericMenu genericMenu = new GenericMenu();
            genericMenu.AddItem(new GUIContent("Create Layer Node"),
                                false,
                                () => OnClickCreateNewLayer(pos));
            genericMenu.ShowAsContext();
        }

        /// <summary>
        /// 点击了创建新Layer节点
        /// </summary>
        /// <param name="mousePosition"></param>
        private void OnClickCreateNewLayer(Vector2 mousePosition) {
            LayerNode layerNode = new LayerNode(mousePosition,
                                                this,
                                                GUIStyleUtil.layerNodeStyle,
                                                GUIStyleUtil.selectedLayerNodeStyle,
                                                OnConnecteToLayerNode,
                                                OnDeleteLayerNode);
            layerNodeList.Add(layerNode);
        }

        #endregion



        #region About Layer Node Things

        private void OnConnecteToLayerNode(LayerNode layerNode) {

        }

        private void OnDeleteLayerNode(LayerNode layerNode) {
            
        }


        /// <summary>
        /// 绘制LayerNode
        /// </summary>
        private void DrawLayerNodes() {
            for (int i = 0; i < layerNodeList.Count; ++i) {
                layerNodeList[i].Draw();
            }
        }

        /// <summary>
        /// 处理跟LayerNode相关的事件
        /// </summary>
        /// <param name="e"></param>
        private bool ProcessLayersEvent(Event e) {
            for(int i = layerNodeList.Count - 1; i >= 0; --i) {
                if (layerNodeList[i].ProcessEvent(e)) {
                    return true;
                }
            }
            return false;
        }
        #endregion



        #region About Connection Things
        private void OnDeleteConnection(Connection _connection) {

        }

        #endregion

    }
}
